package com.sc.tasks;

import com.sc.configs.SysSettings;
import com.sc.entity.bo.DeviceMemBo;
import com.sc.entity.dto.DeviceDto;
import com.sc.entity.params.DeviceOnlineBatchParam;
import com.sc.entity.params.DeviceOnlineParam;
import com.sc.entity.params.DeviceRegisterParam;
import com.sc.services.IotPlatformService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

@RequiredArgsConstructor
@Slf4j
public class TaskUtils {

    public static String registerDevice(IotPlatformService iotPlatformService,
                                        DeviceMemBo device, SysSettings settings) {
        DeviceRegisterParam param = new DeviceRegisterParam();
        param.setVendorPlatformId(settings.getVendorPlatformId());
        param.setPlatformToken(settings.getPlatformToken());
        param.setDeviceModelId(settings.getDeviceModelId());
        param.setDeviceId(device.getId());
        param.setDeviceName(!StringUtils.isEmpty(device.getName()) ? device.getName() : "");
        param.setProductId(settings.getProductId());
        param.setDeviceType(settings.getDeviceType());
        param.setTimeout(settings.getTimeout());
        param.setSubType(device.getSubType());

        log.debug("Ready to register {}", device.getId());
        DeviceDto deviceDto = iotPlatformService.registerDevice(settings.getRegisterUrl(), param);
        if (deviceDto != null && !StringUtils.isEmpty(deviceDto.getDeviceIdentityId())) {
            log.info("Device {} registered OK", device.getId());
            device.setToken(deviceDto.getDeviceIdentityId());
            return deviceDto.getDeviceIdentityId();
        } else {
            log.error("Register device {} error", device.getId());
            return null;
        }
    }

    public static void registerAndUpdateDevice(DeviceMemBo device,
                                               IotPlatformService iotPlatformService, SysSettings settings) {
        String token = registerDevice(iotPlatformService, device, settings);
        if (!StringUtils.isEmpty(token)) {
            device.setRegistered(true);
        }

        log.debug("Device {} registered result {}", device.getId(), !StringUtils.isEmpty(token));
    }

    public static boolean UpdateOnlineBatch(List<DeviceMemBo> devices, IotPlatformService iotPlatformService, SysSettings settings) {
        DeviceOnlineBatchParam batchParam = new DeviceOnlineBatchParam();

        for (var device : devices) {
            if (StringUtils.isEmpty(device.getToken())) {
                log.warn("设备{}未获取正确Token", device.getId());
            }

            DeviceOnlineParam param = new DeviceOnlineParam();
            param.setOnline(device.getOnline());
            param.setDeviceId(device.getId());
            param.setAccessToken(device.getToken());

            batchParam.getParams().add(param);
            batchParam.setNum(batchParam.getNum() + 1);
        }

        if (batchParam.getParams().isEmpty()) {
            return false;
        }

        log.info("UpdateOnlineBatch with {}", batchParam.getParams().size());
        return iotPlatformService.sendOnlineBatch(settings.getOnlineUrl(), batchParam);
    }

    public static boolean updateOnline(DeviceMemBo device, IotPlatformService iotPlatformService, SysSettings settings) {
        if (StringUtils.isEmpty(device.getToken())) {
            log.info("设备{}未获取正确Token", device.getId());
            return false;
        }

        DeviceOnlineParam param = new DeviceOnlineParam();
        param.setOnline(device.getOnline());
        param.setDeviceId(device.getId());

        var result = iotPlatformService.sendOnline(settings.getOnlineUrl(), device.getToken(), param);
        log.debug("Send online {} for device {}", device.getOnline(), device.getId());

        return result;
    }

    public static void registerOrUpdateDevices(ConcurrentHashMap<String, DeviceMemBo> deviceDict,
                                               IotPlatformService iotPlatformService, SysSettings settings) {
        for (var device : deviceDict.values()) {
            if (device == null) {continue;}

            if (!device.getRegistered()) {
                String token = registerDevice(iotPlatformService, device, settings);
                if (!StringUtils.isEmpty(token)) {
                    device.setRegistered(true);
                    device.setToken(token);
                }
                log.debug("Register device {} with result {}", device.getId(), !StringUtils.isEmpty(token));
            }

            if (device.getStatusChanged()) {
                var result = updateOnline(device, iotPlatformService, settings);
                if (result) {
                    device.setStatusChanged(false);
                }
                log.debug("Device {} online has changed ,update with result {}", device.getId(), result);
            }
        }
    }












}
